<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" >

<title>.NetCore项目SignalR获取客户端信息的测试 | 没想好的个人博客</title>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<!-- <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> -->
   <!-- Font Awesome CSS-->
   <link href="https://cdn.bootcss.com/font-awesome/5.13.0/css/all.css" rel="stylesheet">

   <link rel="stylesheet" href="https://cdn.bootcss.com/font-awesome/5.7.2/css/all.min.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">

<link rel="shortcut icon" href="https://shixixiyue.gitee.io//favicon.ico?v=1709791195950">
<link rel="stylesheet" href="https://shixixiyue.gitee.io//styles/main.css">



<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
<script src="https://jsd.onmicrosoft.cn/npm/vue/dist/vue.js"></script>


<style>
  .hljs-ln{
    padding-bottom: 1.2rem;
    margin: 0rem !important;
  }
  .hljs-ln td {
    border: none !important;
    padding: 2px 6px !important;
    line-height: 1.2rem;
    font-size: 1rem;
  }
  .hljs-ln tr td:first-child  {
    color: cadetblue;
    border-right: 1px solid !important;
  }
  .hljs-ln tr {
    border: none !important;
  }
</style>

    <meta name="description" content="
.Net7 新增了 SignalR 可以获取客户端数据的方法，即原方法 InvokeAsync 支持返回值，这里结合官网做了测试，作为记录







1. SignalR注入
2. 环境搭建
3. 升级本地SignalRJS
4. 服..." />
    <meta name="keywords" content=".Net Core" />
  </head>
  <body>
    <div id="app" class="main">

      <div class="sidebar" :class="{ 'full-height': menuVisible }">
  <div class="top-container" data-aos="fade-right">
    <div class="top-header-container">
      <a class="site-title-container" href="https://shixixiyue.gitee.io/">
        <img src="https://shixixiyue.gitee.io//images/avatar.png?v=1709791195950" class="site-logo">
        <h1 class="site-title">没想好的个人博客</h1>
      </a>
      <div class="menu-btn" @click="menuVisible = !menuVisible">
        <div class="line"></div>
      </div>
    </div>
    <div>
      
        
          <a href="https://shixixiyue.gitee.io/" class="site-nav">
            首页
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/4gOKry8Qv/" class="site-nav">
            .Net Core
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/njETBpqXu/" class="site-nav">
            FineUICore
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/XyXyeLOBB" class="site-nav">
            读书笔记
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/TyVX6hfCJ" class="site-nav">
            Vue笔记
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/3Hz2sPtzO/" class="site-nav">
            产品
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tag/Db1wShB_E" class="site-nav">
            其他
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io/" class="site-nav">
            一一一一一一一一一
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//archives" class="site-nav">
            文章归档
          </a>
        
      
        
          <a href="https://shixixiyue.gitee.io//tags" class="site-nav">
            全部标签
          </a>
        
      
    </div>
  </div>
  <div class="bottom-container" data-aos="flip-up" data-aos-offset="0">
    <div class="social-container">
      
        
      
        
      
        
      
        
      
        
      
    </div>
    <div class="site-description">
      没事啥都说
    </div>
    <div class="site-footer">
      QQ：<a href="tencent://message/?uin=935732994&Site=''&Menu=yes">935732994<a/> <a href="http://beian.miit.gov.cn">京ICP备2024045283号<a/> | <a class="rss" href="https://shixixiyue.gitee.io//atom.xml" target="_blank">RSS</a>
    </div>
  </div>
</div>


      <div class="main-container">
        <div class="content-container" data-aos="fade-up">
          <div class="post-detail">
            <h2 class="post-title">.NetCore项目SignalR获取客户端信息的测试</h2>
            <div class="post-date">2023-04-06
            
                
                  <a href="https://shixixiyue.gitee.io/tag/4gOKry8Qv/" class="tag">
                    .Net Core
                  </a>
                
            </div>
            
              <div class="feature-container" style="background-image: url('https://shixixiyue.gitee.io//post-images/netcore-xiang-mu-signalr-huo-qu-ke-hu-duan-xin-xi-de-ce-shi.png')">
              </div>
            
            <div class="post-content" v-pre>
              <blockquote>
<p>.Net7 新增了 SignalR 可以获取客户端数据的方法，即原方法 InvokeAsync 支持返回值，这里结合官网做了测试，作为记录</p>
</blockquote>
<!-- more -->
<p><ul class="markdownIt-TOC">
<li>
<ul>
<li>
<ul>
<li><a href="#1-signalr%E6%B3%A8%E5%85%A5">1. SignalR注入</a></li>
<li><a href="#2-%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA">2. 环境搭建</a></li>
<li><a href="#3-%E5%8D%87%E7%BA%A7%E6%9C%AC%E5%9C%B0signalrjs">3. 升级本地SignalRJS</a></li>
<li><a href="#4-%E6%9C%8D%E5%8A%A1%E7%AB%AF">4. 服务端</a></li>
<li><a href="#5-%E5%AE%A2%E6%88%B7%E7%AB%AF">5. 客户端</a></li>
<li><a href="#6-%E5%BA%94%E7%94%A8">6. 应用</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</p>
<h3 id="1-signalr注入">1. SignalR注入</h3>
<p>路</p>
<h3 id="2-环境搭建">2. 环境搭建</h3>
<p>继续略</p>
<h3 id="3-升级本地signalrjs">3. 升级本地SignalRJS</h3>
<p>结合这两个地址</p>
<p><a href="https://learn.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-7.0&amp;tabs=visual-studio">ASP.NET Core SignalR JavaScript 客户端</a></p>
<p><a href="https://cdnjs.com/libraries/microsoft-signalr">microsoft-signalr</a></p>
<p>注意js版本号7.0+，下到本地也行，从vs2022添加客户端也行，如果本地低在调用js方法后会显示版本不支持；</p>
<h3 id="4-服务端">4. 服务端</h3>
<pre><code>/// &lt;summary&gt;
/// 得到客户端结果
/// &lt;/summary&gt;
/// &lt;param name=&quot;evname&quot;&gt;&lt;/param&gt;
/// &lt;param name=&quot;msg&quot;&gt;&lt;/param&gt;
/// &lt;param name=&quot;id&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
public static async Task&lt;dynamic&gt; GetHubMessage(string evname, string msg, string id = &quot;&quot;)
{
	//尝试拿一个hubid
	if (string.IsNullOrEmpty(id)) { id = GetHubID(); }
	if (string.IsNullOrEmpty(id)) { return default; }
	var Hub = PageContext.GetServerByApp&lt;IHubContext&lt;SignalRHub&gt;&gt;();
	var msr = await Hub.Clients.Client(id).InvokeAsync&lt;dynamic&gt;(evname, msg, new CancellationToken());
	return msr ?? default;
}

/// &lt;summary&gt;
/// 尝试得到本次的hubid
/// &lt;/summary&gt;
/// &lt;returns&gt;&lt;/returns&gt;
public static string GetHubID()
{
	var hubid = string.Empty;
	var head = PageContext.Current!.Request.Headers;
	if (head.ContainsKey(&quot;hubid&quot;))
	{
		hubid = head[&quot;hubid&quot;];
	}
	else if (PageContext.Current!.Request.Form.ContainsKey(&quot;hubid&quot;))
	{
		hubid = PageContext.Current!.Request.Form[&quot;hubid&quot;];
	}
	return hubid;
}
</code></pre>
<p>以上代码 核心方法就是 InvokeAsync ，其他都来自服务就可以了，注意接收值，前台的返回我测试了 数组 对象，后台的接到到的类型是 <code>System.Text.Json</code> , 而不是 <code>Newtonsoft.Json</code>，尽量返回字符串比较稳定；用的时候直接调用即可 <code>GetHubMessage(&quot;getMessage&quot;,&quot;Grid1&quot;);</code></p>
<p>我这里触发的前端方法是 <code>getMessage</code> 如果前端没有注册 getMessage ，则会提示<br>
<code>Client didn't provide a result.（客户端没有返回结果）</code></p>
<h3 id="5-客户端">5. 客户端</h3>
<pre><code>const connection = new signalR
	.HubConnectionBuilder()
	.withUrl(&quot;/HomeHub&quot;)
	.build();

window.hub.connection = connection;
...
window.hub.connection.on(`getMessage`,async (msg)=&gt;{
    return JSON.stringify(F.ui[msg].fields);
});
</code></pre>
<p>这里注意了，我的<code>HomeHub</code>连接是在顶层框架页面，即只有一个实例，如果同一个实例注册多个方法即<code>getMessage</code>并返回结果，会报错，<code>Client provided multiple results(客户端提供了多个结果)</code>;</p>
<h3 id="6-应用">6. 应用</h3>
<p>这样就拿到数据了，那在什么情况下会用到呢，场景要有几个特点，数据回发提交的时候有的参数没带着，或者带不了；或者这是客户端还没有数据，等会才有；或者需要等待客户继续操作后才能拿到结果；</p>
<p>一个典型的场景就是确认<code>Confirm</code>，之前我已经将<code>F.confirm</code> 改为异步了，用<code>Promise</code>包一下就行；之前也改造过等待客户响应的方法，使用客户端响应后二次提交从缓存拿到任务再改变状态，绕了一大圈，存在超时和中断问题；升级之后，后台执行到需要客户选择的代码，可以直接由服务端发起，然后等着前台返回就行了，省去了不少代码；</p>
<p>其他应用场景还有待探索。</p>

            </div>
            
              <div class="tag-container">
                
                  <a href="https://shixixiyue.gitee.io/tag/4gOKry8Qv/" class="tag">
                    .Net Core
                  </a>
                
              </div>
            
            
              <div class="next-post">
                <div class="next">下一篇</div>
                <a href="https://shixixiyue.gitee.io/fineuicore-xiang-mu-zu-jian-hua-he-da-bao/">
                  <h3 class="post-title">
                    FineUICore项目组件化和打包
                  </h3>
                </a>
              </div>
            

            

          </div>

        </div>
      </div>
    </div>

    <script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script type="application/javascript">

AOS.init();

var app = new Vue({
  el: '#app',
  data: {
    menuVisible: false,
  },
})

</script>


  <script src="//jsd.onmicrosoft.cn/gh/highlightjs/cdn-release@11.5.1/build/highlight.min.js"></script>
  <script>
    hljs.initHighlightingOnLoad();
    //hljs.registerLanguage('mermaid', window.hljsDefineMermaid);
  </script>
  <script src="//jsd.onmicrosoft.cn/npm/highlightjs-line-numbers.js@2.8.0/dist/highlightjs-line-numbers.min.js"></script>
  <script>
    hljs.initLineNumbersOnLoad({
      singleLine: true
    });
  </script>
 <script src="https://jsd.onmicrosoft.cn/npm/mermaid/dist/mermaid.min.js"></script>
   <script>
    mermaid.initialize({
      startOnLoad: true,
      securityLevel: 'loose',
    });
  </script>





  </body>
</html>
